package com.hl.card.credit.utill;


import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;


public class GenerateSignUtil {
	private static String byteArrayToHexString(byte[] b) {
		StringBuilder hs = new StringBuilder();
		String stmp;
		for (int n = 0; b != null && n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1)
				hs.append('0');
			hs.append(stmp);
		}
		return hs.toString().toUpperCase();
	}
	
	public static String getSHA256String(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest messageDigest;
		messageDigest = MessageDigest.getInstance("SHA-256");
		messageDigest.update(str.getBytes("UTF-8"));
		String encodeStr = byteArrayToHexString(messageDigest.digest());
		return encodeStr;
	}
	
	public static <T> Map<String, T> sortMapByKey(Map<String, T> map) {
		if (map == null || map.isEmpty()) {
			return null;
		}
		Map<String, T> sortMap = new TreeMap<String, T>(new MapKeyComparator());
		sortMap.putAll(map);
		return sortMap;
	}
	
	
	public static String buildQueryStringMulti(final Map<String, String[]> map) {
		try {
			final StringBuilder sb = new StringBuilder(map.size() * 8);
			for (final Iterator<Map.Entry<String, String[]>> mapIterator = map
					.entrySet().iterator(); mapIterator.hasNext();) {
				final Map.Entry<String, String[]> entry = mapIterator.next();
				final String key = entry.getKey();
				if (key != null) {
					final String keyEncoded = URLEncoder.encode(key,"UTF-8");	//DEFAULT_ENCODING
					final String[] values = entry.getValue();
					sb.append(keyEncoded);
					sb.append("=");
					if (values != null) {
						for (final Iterator<String> listIt = Arrays.asList(
								values).iterator(); listIt.hasNext();) {
							final Object valueObject = listIt.next();
							sb.append(valueObject != null ? valueObject
									.toString() : "");
							if (listIt.hasNext()) {
								sb.append("&");
								sb.append(keyEncoded);
								sb.append("=");
							}
						}
					}
					if (mapIterator.hasNext()) {
						sb.append("&");
					}
				} else {
					assert false : String.format("Null key in query map: %s",
							map.entrySet());
				}
			}
			return sb.toString();
		} catch (final UnsupportedEncodingException e) {
			throw new UnsupportedOperationException(e);
		}
	}
	
	public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
		Map<String,String[]> hashMap = new HashMap<String, String[]>();
		hashMap.put("merchant_key", new String[]{"a6c4cc11037bd074536a394f25584d77"});
		hashMap.put("order_id",new String[]{"m180301729420180302104130012345678901"});
		hashMap.put("timestamp",new String[]{String.valueOf("1520305365933")});
		Map<String, String[]> sortMapByKey = sortMapByKey(hashMap);
		String buildQueryStringMulti = buildQueryStringMulti(sortMapByKey);
		String sign = getSHA256String(buildQueryStringMulti);
		System.out.println(sign);
	}
}

class MapKeyComparator implements Comparator<String> {
    @Override
    public int compare(String str1, String str2) {
        return str1.compareTo(str2);
    }
}